Add support for End-of-RIB marker elems#258
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for BGP End-of-RIB (EoR) markers (RFC 4724) by emitting a new BGPSTREAM_ELEM_TYPE_END_OF_RIB element, making EoRs visible to consumers across MRT/BMP/RIS Live parsing and filterable via elemtype=endofrib. It also updates output formatting to represent (or intentionally omit) EoRs depending on the output format, and fixes a RIS Live record-reuse bug that could otherwise cause mis-processing.
Changes:
- Add EoR detection in the shared UPDATE processing path and emit
BGPSTREAM_ELEM_TYPE_END_OF_RIB. - Add
endofribelement-type filtering support and ASCII output support (E), while deliberately omitting EoRs from bgpdump-compatible output. - Fix RIS Live format state reuse by clearing
msg_typewhen recycling record data.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/bgpreader.c | Documents E elem type in ASCII header and skips empty bgpdump lines (needed for EoR omission). |
| lib/formats/bs_format_rislive.c | Clears recycled msg_type to avoid stale-type reprocessing. |
| lib/formats/bgpstream_parsebgp_common.h | Adds eor_done flag to ensure one EoR elem per UPDATE record. |
| lib/formats/bgpstream_parsebgp_common.c | Implements EoR detection and emission in shared UPDATE processing. |
| lib/bgpstream_record.c | Adds elemtype-mask filtering for the new END_OF_RIB elem type. |
| lib/bgpstream_filter.h | Introduces BGPSTREAM_FILTER_ELEM_TYPE_END_OF_RIB mask bit. |
| lib/bgpstream_filter.c | Parses elemtype=endofrib and sets the new mask bit. |
| lib/bgpstream_elem.h | Adds BGPSTREAM_ELEM_TYPE_END_OF_RIB enum value. |
| lib/bgpstream_elem.c | Adds ASCII type char E and custom ASCII serialization for END_OF_RIB. |
| lib/bgpstream_bgpdump.c | Emits an empty string for END_OF_RIB to stay faithful to original bgpdump output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Tested this with (a lot) of assistance from @0x0ac and it seems to do the right thing. For example: (extra line breaks added by me for legibility) |
| strcmp(buf, exp->prefixes[e]) == 0); | ||
| e++; | ||
| } | ||
| CHECK_MSG(exp->desc, "elem count", e == exp->n_elems); |
BGPStream previously discarded BGP End-of-RIB markers (RFC 4724): they arrive as empty UPDATE messages that yield zero elems, so consumers had no way to tell when a peer had finished sending its initial table dump after a session/graceful restart.
This adds a new BGPSTREAM_ELEM_TYPE_END_OF_RIB elem type. Detection happens in the shared update-processing path (so it covers MRT, BMP, and RIS Live): a completely empty UPDATE is treated as an IPv4-unicast EoR (0.0.0.0/0), and an UPDATE carrying only an empty MP_UNREACH for a unicast AFI is treated as an EoR for that address family (e.g. ::/0 for IPv6). Non-unicast cases are ignored (bgpstream is unicast-only anyway).
The new type is filterable via elemtype
endofriband is included by default (like all other elem types) when no elemtype filter is set. In the native ASCII output it appears with anEtype character; the bgpdump-compatible output deliberately omits it, since the original RIPE bgpdump tool has no representation for EoR markers and we want to stay faithful to that format.Also fixes a latent bug in the RIS Live format plugin where a recycled record slot kept a stale msg_type, which could cause a cleared UPDATE buffer to be reprocessed — previously harmless (zero elems), but it would have produced a spurious EoR elem with this change.